【EKS小ネタ】AWS Load Balancer Controller(LBC)で構築したIngress(ALB)の接続先として正しくServiceが設定されていないとターゲットグループの設定がされない【Backend service does not exist】
こんにちはカスタマーソリューション部のこーへいです!
今回小ネタですが、AWS Load Balancer Controller(以下LBC)で構築したIngress(ALB)のリスナールールにターゲットグループが紐づいておらず困ったので、対処法を備忘録として残しておきます。
「Backend service does not exist」と悲しみのレスポンスが返ってきました。
結論
Ingressの接続先のServiceが正しく存在するか確認しましょう
- Ingressの中で指定したService名が正しいのか確認(今回はこちらでした)
- そもそもServiceを建て忘れていないか確認
解説
backend: service: name: sample-sample-service # 接続するService port: number: 80
上記はingress.yamlの一部(全体版は後ほど折りたたみで載せています)ですが、接続するserviceのnameにて「sample-sample-service(実際は別の値)」を指定しています。
kind: Service metadata: name: sample-service
一方こちらはservice.yamlの一部で、metadataにて「sample-service」と名付けられています。
つまりingress.yamlで指定したservice名にて対象のものがなかったため(今回は間違った値を指定したため)、ALBに代理アクション(503レスポンス)が設定されていたわけです。
Ingress.yamlの全体版
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: alb.ingress.kubernetes.io/scheme: internet-facing # 外部からのトラフィックを許可 alb.ingress.kubernetes.io/target-type: ip # Ipをターゲットに設定 name: sample-ingress spec: ingressClassName: alb # ingressのクラス名を定義 rules: - http: # httpルール paths: - path: / pathType: Prefix backend: service: name: sample-service # 接続するService port: number: 80
service.yamlの全体版
apiVersion: v1 kind: Service metadata: name: sample-service spec: ports: # Podへのアクセスに使用するport - port: 80 targetPort: 80 protocol: TCP type: ClusterIP # クラスター内Pod通信 selector: app: nginx
コード参考:【Amazon EKS】第二回 ALBを利用してNginx Podに負荷分散設定をしてみた!
おまけ
これで終わりはちょっと寂しいので、Ingress周りの知識を軽くさらって(推測して)いきます。
Ingressのターゲットタイプにてipを指定した場合の通信について
metadata: annotations: alb.ingress.kubernetes.io/scheme: internet-facing # 外部からのトラフィックを許可 alb.ingress.kubernetes.io/target-type: ip # Ipをターゲットに設定
上記は先ほど載せたingress.yamlファイルの一部記述ですが、ターゲットタイプにipが指定されています。
これはAWSのターゲットグループにpodが直接登録(ちなみにinstanceを指定した場合はnodeが登録)されるようになる設定です。
Pods を ALB のターゲットとして登録します。ALB に到達するトラフィックは、サービスの Pods に直接ルーティングされます。
Amazon EKS でのアプリケーション負荷分散においてトラフィックの流れについて記述がされています。
Ingressは通常Service(Nodeportが多い)を経由する
Ingressより
上記図の通り、基本的にIngressはServiceを通じてpodにトラフィックが流れます。
一方でIngress(ALB)のターゲットタイプにてipを選択した場合は、先述通りpodに直接トラフィックが流れる仕組みになっています。
ターゲットグループに登録されるpodはおそらくLBCがコントロールしている
ここからはドキュメントから記述を探し当てることができなかったため推測も混じります(見つけ次第追記します)が、実際にトラフィックがIngressからServiceを経由するかは設定によって異なります。
例えばALBの場合だと、ターゲットタイプにinstanceを指定した場合Service(Nodeport等)を経由する一方で、ipの場合は直接podにトラフィックが流れます。
しかしipの場合はService(今回はClusterIP)を指定が必要ないかと言われたらそうではなく、Serviceの指定がないと本記事の通りALBのリスナールールにて適切なターゲットグループが紐づけられません。
How AWS Load Balancer controller worksより
ALBの場合、IngressリソースをK8s上でapplyすると自動的にALBが作成されますが、その作成を担っているのがpodとして存在するLBC(AWS Load Balancer Controller)です(これは事実)。
The controller watches for ingress events from the API server. When it finds ingress resources that satisfy its requirements, it begins the creation of AWS resources.
How AWS Load Balancer controller worksより
その上で以下を推測したというのが今回の結論です。
- LBCはIngress側で指定したServiceを確認し、Service側で指定されたpodをターゲットグループに登録する
まとめ
前半パートは小ネタの回答、後半パートは周辺知識のメモのブログ記事となりました。
後半部分に関しては大きく間違ってはいないだろうと思いつつも、公式の記述を見つけ次第追記させていただきます。
参考
- https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/alb-ingress.html
- https://aws.github.io/aws-eks-best-practices/networking/loadbalancing/loadbalancing/
- https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/